簡單介紹一下變數在JS中的幾個性質,之後的篇章會比較深入的講解,這些性質背後的原因們
var a=1;
var b='2'
var c=function(){return 3}
var d=false
console.log(typeof a);  //number
console.log(typeof b);  //string
console.log(typeof c);  //function
console.log(typeof d);  //boolean
JS不像Java一樣用int, String, boolean等關鍵字宣告變數。
JS的變數在ES6以前只有var,ES6以後也頂多新增了let, const,變數的typeof都需要等到賦值才能決定。
var a;
console.log(a);        //undefined
console.log(typeof a); //undefined
用var宣告變數,初始化為undefined。還沒賦值前,無法判斷該變數的type
小結論:變數的type,用變數的value判斷
有效範圍講的專業一點叫作用域(scope),var變數是遵照 function scope。
就是變數存在的地方。
有點像寄生物與宿主的關係,寄生物離開宿主多久就會死掉。
變數離開他的作用域,就會被垃圾回收機制給丟掉。燈燈燈燈燈燈燈燈燈,垃圾車來囉~
function scope」講人話就是:var關鍵字令出的變數,他的有效範圍以function界定。
console.log('用var關鍵字 定義變數i')
console.log('--------------------------')
var i='全域變數';
console.log(`i=${i}`);  
//`i=${i}` 等價於 'i='+i 字串連接
// ` 反引號在~鍵上面 (我一開始還找不到,所以特別寫這行)
console.log('--------------------------')
function fun(){
	var i='function內變數';
	console.log(`I'm in the function, i=${i}`)
};
fun(); 
console.log('--------------------------')
        
console.log(`I'm out of the function, i=${i}`);  
console.log('--------------------------')
        
console.log("I'm in the for loop")
for(var i=0;i<5;i++){
	console.log(`i=${i}`) 
}  //i=5離開for迴圈
console.log('--------------------------')
console.log(`I'm out of the for loop, i=${i}`); 
用var關鍵字 定義變數i
--------------------------
i=全域變數
--------------------------
I'm in the function, i=function內變數
--------------------------
I'm out of the function, i=全域變數
--------------------------
I'm in the for loop
i=0
i=1
i=2
i=3
i=4
--------------------------
I'm out of the for loop, i=5
離開for loop後,我們再次呼叫變數i,得到的答案是:5。
原因是for loop 不是function,會影響到在全域用var定義的變數i。
var i='全域變數';
function outterFun(){
	function innerFun(){
			console.log(i)
	}
	return innerFun;
};
aNewFun=outterFun();       
aNewFun();   //全域變數
outterFun裡面的inner function,找不到變數i → 往外向outterFun找outterFun找不到變數i →向全域找Uncaught ReferenceError: i is not defined
小結論:
function scope
首先先來釐清變數和屬性,他們有以下幾個關係:
一般情況,變數放在一個object裡面,那該變數就會叫object的屬性
function雖然是一個object,但var變數的作用域(scope)是以function為界,
所以function外,別想拿到function的內變數
function外,如果硬要存取內變數,可以把它從function return出來,變得與function本身同級。
function外,可以存取屬性。
沒錯,你沒看錯,function可以有屬性,因為function是object嘛~~
function aFun(){
        let a='function內變數';
        return a;   //可以透過return,讓function外,可以取出內變數
    }
aFun.a='function物件屬性';
console.log(`aFun.a= ${aFun.a}`)    // aFun.a= function物件屬性
console.log(`aFun return a= ${aFun()}`);   //aFun return a= function內變數
小結論:
function scope
console.log(a);
fun();
console.log('----------')
function fun(){
	console.log(b)
	var b=2;
}
var a=1;
var a;    //初始化undefined
function fun(){
	var b	 //初始化undefined
	console.log(b)
	b=2;
}
console.log(a);   //undefined
fun();            //undefined
console.log('----------')
a=1;
console.log(a);   //1
var a='全域a'; 
console.log(`a=${a}`)
console.log(`a=${fun('實參')}`)
outerfun();
fun1();
          
function outerfun(){
	a='在outerfun中改a值'
	var a='outterfun a'
	for(var a=0;a<5;a++){
		console.log(`a=${a}`?)
		a='for loop裡面的a'
		console.log(`a=${a}`)
	}
	console.log(`a=${a}`);
	function innerfun(){
		console.log(`a=${a}`);
	}
	innerfun();
}
function fun(a){
	return a;
}
function fun1(){
	a='在fun1中改a值'
}
console.log(`a=${a}`)
小提醒:變數前面沒寫var,要嘛是引用自己或是引用外層的變數,
要嘛就是新建全域變數,但這種不會提升
.
.
.
.
.
.
.
.
.
.
.
a=全域a
a=實參
a=0
a=for loop裡面的a
a=NaN
a=NaN
a=在fun1中改a值
//模擬:for迴圈裡的a
var num='我是字串,我要先被加1,再被轉成number'
num+=1                  //'我是字串,我要先被加1,再被轉成number1'
num =Number(num)        //string轉number
console.log(num)        //NaN
console.log(typeof num) //number
//模擬:判斷是否離開for迴圈
//句型:(判斷句)?true執行:fales執行
console.log((NaN<5)?'yes':'no')  //no,離開for迴圈
a在各個function scope中,被改值的過程